#include "slist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static node_t *__node_create(slist_t *s, void *data)
{
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == s || NULL == data)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    tmp = malloc(sizeof(node_t));
    if (NULL == tmp)
    {
        perror("tmp malloc failed...");
        goto err0;
    }
    memset(tmp, 0, sizeof(node_t));

    // 创建类型大小
    tmp->data = malloc(s->size);
    if (NULL == tmp->data)
    {
        perror("tmp_data malloc failed...");
        goto err1;
    }
    memset(tmp->data, 0, s->size);

    // 拷贝数据
    memcpy(tmp->data, data, s->size);
    tmp->next = NULL;

    s->count++;

    return tmp;

err1:
    free(tmp);
    tmp = NULL;
err0:
    return NULL;
}


// 创建头信息结构体
int slist_create(slist_t **s, int size, ft1 my_destroy)
{

    // 参数检查
    if (size < 0 || NULL == my_destroy)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建结构体
    *s = malloc(sizeof(slist_t));
    if (NULL == *s)
    {
        perror("*s malloc failed...");
        goto err0;
    }
    memset(*s, 0, sizeof(slist_t));

    // 初始化
    (*s)->count = 0;
    (*s)->my_destroy = my_destroy;
    (*s)->p = NULL;
    (*s)->size = size;


    return 0;
err0:
    return -1;
}

// 尾插
int slist_append(slist_t *s, void *data)
{
    node_t *new_node = NULL;
    node_t *tmp = NULL;

    // 参数检查
    if (NULL == s || NULL == data)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    new_node = __node_create(s, data);

    // 尾部插入
    tmp = s->p;
    if (tmp == NULL)
    {
        s->p = new_node;
    }
    else
    {
        while (NULL != tmp->next)
        {
            tmp = tmp->next;
        }
        new_node->next = tmp->next;
        tmp->next = new_node;
    }





    return 0;
err0:
    return -1;
}



// 头插
int slist_prepend(slist_t *s, void *data)
{
    node_t *new_node = NULL;

    // 参数检查
    if (NULL == s || NULL == data)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 创建节点
    new_node = __node_create(s, data);

    // 节点头部插入
    new_node->next = s->p;
    s->p = new_node;


    return 0;
err0:
    return -1;
}


// 链表的遍历
int slist_traverse(slist_t *s, ft1 my_print)
{

    node_t *tmp = NULL;

    // 参数检查
    if (NULL == s || NULL == my_print)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 遍历
    tmp = s->p;
    while (NULL != tmp)
    {
        my_print(tmp);

        tmp = tmp->next;
    }
    printf("\n");



    return 0;
err0:
    return -1;
}

// 链表的销毁
int slist_destroy(slist_t *s)
{
    node_t *tmp = NULL;
    node_t *save = NULL;


    // 参数检查
    if (NULL == s)
    {
        perror("argument lawless...");
        goto err0;
    }

    // 销毁
    tmp = s->p;
    while (NULL != tmp)
    {
        // 保存
        save = tmp->next;

        // 销毁哦
        s->my_destroy(tmp);
        s->count--;

        // 指向下一个
        tmp = save;
    }

    s->p = NULL;

    return 0;
err0:
    return -1;
}

// 链表的检索插入
int slist_insert_by_index(slist_t *s, void *data, int index)
{
    int idx = index - 1;
    int i = 0;
    node_t *tmp = NULL;
    node_t *save = NULL;

    // 参数检查
    if (NULL == s || NULL == data)
    {
        perror("argument lawless...");
        goto err0;
    }

    if (idx < 0)
    {
        goto err0;
    }
    else if (idx >= s->count)
    {
        slist_append(s, data);
    }
    else if (idx == 0)
    {
        slist_prepend(s, data);
    }
    else 
    {
        // 创建节点
        tmp = __node_create(s, data);

        save = s->p;
        for (i = 0; i < idx - 1; i++)
        {
            save = save->next;
        }

        tmp->next = save->next;
        save->next = tmp;
    }


    return 0;
err0:
    return -1;
}

// 链表检索删除
int slist_delete_by_index(slist_t *s, int index)
{   
    int i = 0;
    int idx = index - 1;
    node_t *tmp = NULL;
    node_t *save = NULL;


    // 参数检查
    if (NULL == s)
    {
        perror("argument lawless...");
        goto err0;
    }

    if (index < 1 || index > s->count)
    {
        goto err0;
    }
    else if (index == 1)
    {
        save = s->p->next;
        s->my_destroy(s->p);
        s->p = save;
    }
    else if (s->count == 1)
    {
        s->my_destroy(s->p);
        s->p = NULL;
    }
    else 
    {
        tmp = s->p;
        for (i = 0; i < idx - 1; i++)
        {
            tmp = tmp->next;
        }
        save = tmp->next->next;
        s->my_destroy(tmp->next);
        tmp->next = save;
    }

    s->count--;

    return 0;
err0:
    return -1;
}

// 链表的排序
int slist_sort(slist_t *s, ft2 my_compare)
{
    node_t *node_i = NULL;
    node_t *node_j = NULL;
    node_t *node_min = NULL;
    node_t *tmp = NULL;
    int num = 0;

    // 参数检查
    if (NULL == s)
    {
        perror("argument lawless...");
        goto err0;
    }

    tmp = __node_create(s, &num);

    

    // 排序
    for (node_i = s->p; node_i->next != NULL; node_i = node_i->next)
    {
        node_min = node_i;
        for (node_j = node_min->next; node_j != NULL; node_j = node_j->next)
        {
            if (my_compare(node_min, node_j) > 0)
            {
                node_min = node_j;
                printf("1\n");
            }
        }

        if (node_min != node_i)
        {
            printf("%lu\n", sizeof(node_t) - sizeof(node_t *));
            memcpy(tmp, node_i, sizeof(node_t) - sizeof(node_t *));
            memcpy(node_i, node_j, sizeof(node_t) - sizeof(node_t *));
            memcpy(node_j, tmp, sizeof(node_t) - sizeof(node_t *));
        }
    }

    return 0;
err0:
    return -1;
}